<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>依赖注入 Dependency Injection</title>
<link rel="stylesheet" href="../lib/bootstrap3/css/bootstrap.min.css">
<link rel="stylesheet" href="../lib/bootstrap3/css/dashboard.css">
<script src="../lib/angularjs/angular.min.js"></script>
</head>
<body>
<h2>AngularJS Sample Application</h2>
<div ng-app="app">
    <div class="well row" ng-controller="DI01">
        <div class="col-sm-3">
            <h4>推断式注入声明</h4>
            <button class="btn-success btn" ng-click="sayHello()">点击</button>
            <div class="alert alert-danger"><h2>{{message}}</h2></div>
            <div class="alert alert-info">这种注入方式，需要在保证参数名称与服务名称相同。如果代码要经过压缩等操作，就会导致注入失败。</div>
        </div>
        <div class="col-sm-9">
            <xmp>
                /** 推断式注入声明 **/
                app.controller('DI01',function ($scope,greater) {
                    $scope.message=greater.great(Math.random());
                    $scope.sayHello=function () {
                        $scope.message=greater.great(Math.random());
                    }
                });
            </xmp>
        </div>
    </div>
    <div class="well row" ng-controller="DI02">
        <div class="col-sm-3">
            <h4>显式注入声明</h4>
            <button class="btn-success btn" ng-click="sayHello()">点击</button>
            <div class="alert alert-danger"><h2>{{message}}</h2></div>
            <div class="alert alert-info">这种注入方式，需要设置一个依赖数组，数组内是依赖的服务名字，在函数参数中，可以随意设置参数名称，但是必须保证顺序的一致性。</div>
        </div>
        <div class="col-sm-9">
            <xmp>
                /** 显式注入声明 **/
                app.controller('DI02',di02ctrl);
                function di02ctrl(a,b) {
                    a.message=b.great(Math.random());
                    a.sayHello=function () {
                        a.message=b.great(Math.random());
                    }
                }
                di02ctrl.$inject = ['$scope', 'greater'];/** 如果没有这个，di02ctrl方法接收的参数名必须是【$scope,greater】，这样压缩的时候代码就会报错。 **/
            </xmp>
        </div>
    </div>
    <div class="well row" ng-controller="DI03">
        <div class="col-sm-3">
            <h4>行内注入声明</h4>
            <button class="btn-success btn" ng-click="sayHello()">点击</button>
            <div class="alert alert-danger"><h2>{{message}}</h2></div>
            <div class="alert alert-info">这种注入方式直接传入两个参数，一个是名字，另一个是一个数组。这个数组的最后一个参数是真正的方法体，其他的都是依赖的目标，但是要保证与方法体的参数顺序一致（与标记注入一样）。</div>
        </div>
        <div class="col-sm-9">
            <xmp>
                /** 行内注入声明 **/
                app.controller('DI03',['$scope','greater',function (a,b) {
                    a.message=b.great(Math.random());
                    a.sayHello=function () {
                        a.message=b.great(Math.random());
                    }
                }]);
            </xmp>
        </div>
    </div>
    <div class="well"  ng-controller="CalcController">
        <p>Enter a number: <input type="number" ng-model="number" />
            <button ng-click="square()">X<sup>2</sup></button>
        <p>Result: {{result}}</p>
    </div>
</div>
<script>
    var app = angular.module("app", []);
    app.factory('greater',function () {
        return {
            great:function (msg) {
                return ('Hello '+msg);
            }
        }
    });
</script>
<script>
    /** 推断式注入声明 **/
    app.controller('DI01',function ($scope,greater) {
        $scope.message=greater.great(Math.random());
        $scope.sayHello=function () {
            $scope.message=greater.great(Math.random());
        }
    });
</script>
<script>
    /** 显式注入声明 **/
    app.controller('DI02',di02ctrl);
    function di02ctrl(a,b) {
        a.message=b.great(Math.random());
        a.sayHello=function () {
            a.message=b.great(Math.random());
        }
    }
    di02ctrl.$inject = ['$scope', 'greater'];/** 如果没有这个，di02ctrl方法接收的参数名必须是【$scope,greater】，这样压缩的时候代码就会报错。 **/
</script>
<script>
    /** 行内注入声明 **/
    app.controller('DI03',['$scope','greater',function (a,b) {
        a.message=b.great(Math.random());
        a.sayHello=function () {
            a.message=b.great(Math.random());
        }
    }]);
</script>
<script>
    app.config(function($provide) {
        $provide.provider('MathService', function() {
            this.$get = function() {
                var factory = {};
                factory.multiply = function(a, b) {
                    return a * b;
                }
                return factory;
            };
        });
    });
    app.value("defaultInput", 5);
    app.factory('MathService', function() {
        var factory = {};
        factory.multiply = function(a, b) {
            return a * b;
        }
        return factory;
    });
    app.service('CalcService', function(MathService){
        this.square = function(a) {
            return MathService.multiply(a,a);
        }
    });
    app.controller('CalcController', function($scope, CalcService, defaultInput) {
        $scope.number = defaultInput;
        $scope.result = CalcService.square($scope.number);

        $scope.square = function() {
            $scope.result = CalcService.square($scope.number);
        }
    });
</script>
</body>
</html>